#include "ULUI_LookupSingle.h"
#include "ULUI_PredictImpossibleRed.h"
#include "ULGfx_History.h"
#include "ULGfx_CrossHair.h"
#include "ULCore_Prediction.h"
#include "ULCore_PredictImpossibleRed.h"
#include "ULCore_Algorithm.h"
#include "ULCore_RandomPool.h"
#include "UL_Global.h"
#include "UL_Tools.h"
#include "VSDL_tools.h"

#define PREDICT_IMPOSSIBLERED_START_X	100
#define PREDICT_IMPOSSIBLERED_START_Y	100

static ULC_ACData acData;
static int minusBlue[UL_RED_BALLS_COUNT];
static int minusReds[UL_RED_BALLS_COUNT];
static ULC_Balls ulcBalls;
static bool numberPicked;
int lastAC;
int predictAC;

ULUI_PredictImpossibleRed ULUI_PredictImpossibleRed::predictImpossibleRed;

enum BinLookupIDs{
	EXIT,	
};	

static char *menuTitles[] = {
	"返回"
};

void ULUI_PredictImpossibleRed::Init()
{
	int i;
	VSDL_Point currentXY(PREDICT_IMPOSSIBLERED_START_X, PREDICT_IMPOSSIBLERED_START_Y);
	int w, h;
	ULUI_Menu menu;
	int ret;
	ULG_History *ulgHistory = ULG_History::Instance();

	AttachEventHandler(this);

	menu.SetFont(UL_Global::UnionLottoFont());
	menu.ShowBoarder(true);
	selectedMenu = -1;

	for (i = 0; i <= EXIT; i++){
		menu.SetID(i);
		menu.SetTitle(menuTitles[i]);
		menus.AddMenu(menu);
	}

	menus.SetFirstMenuXY(VSDL_Point(PREDICT_IMPOSSIBLERED_START_X, PREDICT_IMPOSSIBLERED_START_Y));
	menu.GetTitleSize(w, h);

	PredictImpossibleRed(acData, minusBlue, minusReds, *ulgHistory);
	lastAC = acData.ac;
	numberPicked = false;
}

void ULUI_PredictImpossibleRed::CleanUp()
{
	menus.Reset();
}

void ULUI_PredictImpossibleRed::Pause()
{
}

void ULUI_PredictImpossibleRed::Resume()
{
	selectedMenu = -1;
}

void ULUI_PredictImpossibleRed::Update(VSDL_GameEngine *game)
{
	if (selectedMenu == -1){
		return ;
	}

	switch (selectedMenu){
		case EXIT:
			game->PopState();
			break;
	}
}

void ULUI_PredictImpossibleRed::Draw(VSDL_GameEngine *game)
{
	VSDL_RGB rgb(100, 100, 100);
	VSDL_Point currentXY(PREDICT_IMPOSSIBLERED_START_X, PREDICT_IMPOSSIBLERED_START_Y);
	int fontHeight;
	int i;
	char msgBuffer[256];
	char *pBuffer;
	ULG_Serial *ulgSerial = UL_Global::UnionLottoSerial();
	SDL_Surface *destSurf = game->GetSurface();
	int invalidNumbers[UL_BALL_MAX_RED] = {0};
	ULG_Balls *balls = UL_Global::UnionLottoBalls();
	ULC_RandomPool pool;
	ULC_ACData predictedACData;
	
	UL_Global::UnionLottoShowBg();
	UL_Global::UnionLottoShowTitle();
	menus.Show(destSurf);

	fontHeight = UL_Global::UnionLottoGetFontHeight();
	currentXY.y += fontHeight * (EXIT + 1);
	//Draw result rect
	SPG_RectFilled(destSurf, currentXY.x, currentXY.y, destSurf->w, destSurf->h, rgb.GetRGB32(destSurf));

	pBuffer = msgBuffer;
	//Impossible reds using AC
	for (i = 0; i < acData.dtDiff; i++){
		invalidNumbers[acData.dtDataFinal[i] - 1] = 1;
		sprintf(pBuffer, "%02d ", acData.dtDataFinal[i]);
		pBuffer += 3;
	}
	
	UL_Global::UnionLottoShowTip("AC值排除法(排除数量较多，错误号一般在1-2个):", currentXY);
	currentXY.y += fontHeight;
	UL_Global::UnionLottoShowTip(msgBuffer, currentXY);
	currentXY.y += fontHeight;
	
	//Impossible reds using red minus blue
	memset(msgBuffer, 0, 256);
	pBuffer = msgBuffer;
	for (i = 0; i < UL_RED_BALLS_COUNT; i++){
		if (minusBlue > 0){
			invalidNumbers[minusBlue[i] - 1] = 1;
			sprintf(pBuffer, "%02d ", minusBlue[i]);
			pBuffer += 3;
		}
	}
	
	UL_Global::UnionLottoShowTip("红球减蓝球排除法(大部分情况正确，偶尔会错1-2个):", currentXY);
	currentXY.y += fontHeight;
	UL_Global::UnionLottoShowTip(msgBuffer, currentXY);
	currentXY.y += fontHeight;
	
	//Impossible reds using red minus red
	memset(msgBuffer, 0, 256);
	pBuffer = msgBuffer;
	for (i = 0; i < UL_RED_BALLS_COUNT; i++){
		if (minusReds > 0){
			invalidNumbers[minusReds[i] - 1] = 1;
			sprintf(pBuffer, "%02d ", minusReds[i]);
			pBuffer += 3;
		}
	}
	
	UL_Global::UnionLottoShowTip("红球减蓝球排除法(大部分情况正确，偶尔会错1-2个):", currentXY);
	currentXY.y += fontHeight;
	UL_Global::UnionLottoShowTip(msgBuffer, currentXY);
	currentXY.y += fontHeight;
	
	//Recommended reds	
	memset(msgBuffer, 0, 256);
	pBuffer = msgBuffer;
	
	for (i = 0; i < UL_BALL_MAX_RED; i++){
		if (invalidNumbers[i] == 0){
			sprintf(pBuffer, "%02d ", i + 1);
			pool.AddNumber(i + 1);
			pBuffer += 3;
		}
	}
	
	UL_Global::UnionLottoShowTip("推荐红球号:", currentXY);
	currentXY.y += fontHeight;
	UL_Global::UnionLottoShowTip(msgBuffer, currentXY);
	currentXY.y += fontHeight;
	
	//Generate a random combinations
	UL_Global::UnionLottoShowTip("下期红球预测:", currentXY);		
	currentXY.y += fontHeight;
	
	if (numberPicked == false){
		int currentNumber = 0;

		for (i = 0; i < UL_RED_BALLS_COUNT; i++){
			currentNumber = pool.GetNumber();
			while (ulcBalls.IsRedBallExisted(currentNumber)){
					currentNumber = pool.GetNumber();
			}
			
			ulcBalls.reds[i] = currentNumber;
		}
		
		ulcBalls.SortRedBalls();
		numberPicked = true;
	}
	

	*balls = ulcBalls;
	predictedACData.Caculate(balls);
	balls->DisableOutputBlue();
		
	balls->SetFirstBallXY(currentXY);
	balls->Show(destSurf);
	
	currentXY.y += balls->GetRedBallImageHeight();
	sprintf(msgBuffer, "上期AC: %d 预测AC: %d", lastAC, predictedACData.ac);
	UL_Global::UnionLottoShowTip(msgBuffer, currentXY);
}

ULUI_PredictImpossibleRed *ULUI_PredictImpossibleRed::Instance()
{
	return &predictImpossibleRed;
}


void __HANDLE_EVENT ULUI_PredictImpossibleRed::OnKeyDown(SDLKey keysym, unsigned char *keyStates, void *arg)
{
	VSDL_GameEngine *game = reinterpret_cast<VSDL_GameEngine *>(arg);

	if (keyStates[SDLK_ESCAPE]){
		game->PopState();
	}
}

void __HANDLE_EVENT ULUI_PredictImpossibleRed::OnMouseMove(int button, unsigned char buttonState, int absX, int absY, int relX, int relY, void *arg)
{
	int i;

	menus.UpdateMenuList(absX, absY);

}

void __HANDLE_EVENT ULUI_PredictImpossibleRed::OnMouseDown(int button, unsigned char buttonState, int absX, int absY, void *arg)
{
	int i;
	VSDL_GameEngine *game = reinterpret_cast<VSDL_GameEngine *>(arg);

	selectedMenu = -1;

	for (i = 0; i <= EXIT; i++){
		ULUI_Menu &menu = menus.GetMenu(i);

		if (menu.IsXYInRect(absX, absY)){
			selectedMenu = i;
			break;
		}
	}

}

void __HANDLE_EVENT ULUI_PredictImpossibleRed::OnQuit(void *arg)
{
	VSDL_GameEngine *game = reinterpret_cast<VSDL_GameEngine *>(arg);

	game->Quit();
}
